/*
 * Tezad - Classic puzzle game
 * Copyright 2009 Shayne Riley and Paul Maseberg
 *
 * Tezad is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tezad is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tezad.  If not, see <http://www.gnu.org/licenses/>
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * To contact the authors on questions or issues regarding the license,
 * you may send an email to <pezads at gmail dot com>
 */

#ifndef GAMEACTIONS_H_
#define GAMEACTIONS_H_

#include "Command.h"
#include "CommandActions.h"

class MovementAction: public Command
{
public:
    static const int MA_SHIFT_LEFT = 0x1;
    static const int MA_SHIFT_RIGHT = 0x2;
    static const int MA_SOFT_DOWN = 0x4;
    static const int MA_HARD_DOWN = 0x8;
    static const int MA_GRAVITY_DOWN = 0x10;
    static const int MA_SHIFT_UP = 0x20;
    static const int MA_ROTATE_CLOCKWISE = 0x40;
    static const int MA_ROTATE_COUNTERCLOCKWISE = 0x80;

    /**
     * Creates a movement action based upon the number given.
     * @param actionType Choose one of the actions, starts with MA_.
     */
    MovementAction(int actionType);
    virtual ~MovementAction();

    virtual void execute(CommandActions &actions) const;
private:
    int mActionType;
};

class SetMinoAction: public Command
{
public:
    SetMinoAction();
    virtual ~SetMinoAction();
    virtual void execute(CommandActions &actions) const;
};

class NewMinoAction: public Command
{
public:
    /**
     * A new mino must come into play!
     * @param minoNum 0-6 represents I, J, L, O, S, T, Z.
     */
    NewMinoAction(int minoNum);
    virtual ~NewMinoAction();
    virtual void execute(CommandActions &actions) const;
private:
    int mMinoNum;
};

class ClearRowsAction: public Command
{
public:
    /**
     * Clear the indicated rows in the well. These should be ordered from
     * lowest row to highest.
     * @param rows  An array of the rows to clear.
     * @param numRows   The number of elements in the array. Must not be bigger
     * than 4.
     */
    ClearRowsAction(const int rows[], int numRows);
    virtual ~ClearRowsAction();
    virtual void execute(CommandActions &actions) const;
private:
    int mRows[4];
    int mNumRows;
};

class SpeedAction: public Command
{
public:
    /**
     * Action for setting the drop speed of the minos.
     * @param speed The drop speed specifier, in a range between 0-20 inclusive.
     * 0 is slowest, 20 is instant fall.
     */
    SpeedAction(int speed);
    virtual ~SpeedAction();
    virtual void execute(CommandActions &actions) const;
private:
    int mSpeed;
};

class InitGameAction: public Command
{
public:
    /**
     * Constructs an initialization game command, specifying the desired
     * width, height, hidden height, starting row and column of the origin
     * brick of the minos when they get introduced to the well, and starting
     * speed.
     * @param width The width of the well. Must be greater than or equal to 4.
     * @param totalHeight The height of the well. Must be greater or equal to 4.
     * @param hiddenHeight  The portion of the well that is hidden. Must be
     * greater or equal to 0, and cannot be equal to the total height of the
     * well.
     * @param startRow  The starting row of the origin brick of each new mino.
     *  Must be located within the confines of the well, and at least one row
     *  down from the top of the well, and two rows up from the bottom.
     *  Remember, row numbers go from 1 at the bottom to n at the top, so you
     *  would want it at n - 1, most likely.
     * @param startCol  The starting column of the origin brick of each new
     * mino. Must be at least one column in from the left, and two columns in
     * from the right. Column numbers for from 1 at the left to n at the right.
     * @param startSpeed    The starting speed of the mino decent. Must be
     * between 0-20.
     */
    InitGameAction(int width, int totalHeight, int hiddenHeight,
            int startRow, int startCol, int startSpeed);
    virtual ~InitGameAction();
    virtual void execute(CommandActions &actions) const;
private:
    int mWidth;
    int mTotalHeight;
    int mHiddenHeight;
    int mStartRow;
    int mStartCol;
    int mStartSpeed;
};

//class SomeAction: public Command
//{
//public:
//    SomeAction();
//    virtual ~SomeAction();
//    virtual void execute(CommandActions &actions) const;
//};
#endif /* GAMEACTIONS_H_ */
